import xml.dom.minidom as dom
from abstract_node.data_description import SensorProperties, ChannelProperties
import quantities as quantities

class DataSheetParser():

    def load_dimension(self,components):
        dim=1
        for element in components.childNodes: 
            if element.nodeName.strip()=="SIUnit":
                for nodes in element.childNodes: 
                    if nodes.nodeType==1:                       
                        for values in nodes.childNodes:
                            if values.nodeType==1:   
                                content = self.read_node(values)                        
                                if values.nodeName.strip()=="Power":
                                    power=content
                                if values.nodeName.strip()=="Magnitude":
                                    magnitude=content
                        if nodes.nodeName.strip()=="Meter":
                            dim=dim*(10**int(magnitude)*quantities.meter)**int(power)
                        if nodes.nodeName.strip()=="Kelvin":
                            dim=dim*(10**int(magnitude)*quantities.kelvin)**int(power)
                        if nodes.nodeName.strip()=="Second":
                            dim=dim*(10**int(magnitude)*quantities.second)**int(power)
                        if nodes.nodeName.strip()=="Volt":
                            dim=dim*(10**int(magnitude)*quantities.volt)**int(power)
                        if nodes.nodeName.strip()=="Kilogram":
                            dim=dim*(10**int(magnitude)*quantities.kilogram)**int(power)
                        if nodes.nodeName.strip()=="Radian":
                            dim=dim*(10**int(magnitude)*quantities.radian)**int(power)
                        if nodes.nodeName.strip()=="Degree":
                            dim=dim*(10**int(magnitude)*quantities.degree)**int(power)       
        return dim 
                        
    def read_node(self, knoten): 
        string=knoten.firstChild.data.strip()
        if len(string)==0:
            return 0
        if string[0]=='[':
            string=string[1:-1]
            value=eval('[%s(s) for s in string.split(\',\')]'%knoten.getAttribute("type"))
        else:
            value=eval("%s('%s')" % (knoten.getAttribute("type"), 
                                          string))
            if knoten.getAttribute("type")=="bool":
                value=bool(int(string))
        return value    


class SensorDataSheetParser(DataSheetParser):

    def __init__(self, filename):
        self.sensorProperties=SensorProperties()
        self.sensorProperties.sensorDataSheet=filename
    
    def load_datasheet(self):
        baum = dom.parse(self.sensorProperties.sensorDataSheet.__str__())
        self.load_sensor_datasheet(baum)
        return self.sensorProperties
    
    def load_sensor_datasheet(self, baum):   
        aux = baum.getElementsByTagName('SensorDataSheetFile')
        if aux!=[]:
            content = self.read_node(aux[0])
            self.sensorProperties.sensorDataSheet=content
            baum = dom.parse(self.sensorProperties.sensorDataSheet)

        aux = baum.getElementsByTagName('General')
        for element in aux[0].childNodes: 
            if element.nodeType==1:
                content = self.read_node(element)
                if element.nodeName.strip()=="Name":
                    self.sensorProperties.name=content
                if element.nodeName.strip()=="Producer":
                    self.sensorProperties.producer=content
                if element.nodeName.strip()=="Period":
                    for node in element.childNodes:
                        if node.nodeType==1:
                            if node.nodeName.strip()=="Value":
                                self.sensorProperties.period=self.read_node(node)
                            if node.nodeName.strip()=="Dimension":
                                aux = self.load_dimension(node)
                                self.sensorProperties.period=int(self.sensorProperties.period)*aux
        self.load_sensor_properties(baum)
        
    def load_measurement_format(self,baum):
        aux = baum.getElementsByTagName('MeasurementFormat')
        for element in aux[0].childNodes:
            event_element={}
            if element.nodeType==1:
                event_element['Name']=element.nodeName.strip()
                for components in element.childNodes:
                    if components.nodeType==1:
                        if components.nodeName.strip()=="Dimension":
                            content = self.load_dimension(components)
                        else:
                            content = self.read_node(components)
                        event_element[components.nodeName.strip()]=content
                self.sensorProperties.eventFormat.append(event_element)
    
    def load_sensor_properties(self, baum):
        if baum.getElementsByTagName('Sensorbeam')!=[]:
            node = baum.getElementsByTagName('Sensorbeam')[0]
            element = node.getElementsByTagName('Omnidirectional')[0]
            self.sensorProperties.omnidirectional = bool(int(element.firstChild.data.strip()))
            if self.sensorProperties.omnidirectional<> True:
                beams = node.getElementsByTagName('Beams')
                for beam in beams[0].childNodes:
                    if beam.nodeType==1:
                        self.sensorProperties.beams.append(eval(beam.firstChild.data.strip()))
#                dimension = node.getElementsByTagName('Dimension')
#                print dimension.nodeName.strip()=="Dimension"
#                print dimension
#                self.sensorProperties.beams_dimension= 1*self.load_dimension(dimension)  
   
        
        aux = baum.getElementsByTagName('Properties')
        for element in aux[0].childNodes: 
            if element.nodeType==1:
                content = self.read_node(element)
                if element.nodeName.strip()=="Position":
                    for node in element.childNodes:
                        if node.nodeType==1:
                            if node.nodeName.strip()=="Value":
                                self.sensorProperties.position=self.read_node(node)
                            if node.nodeName.strip()=="Dimension":
                                aux = self.load_dimension(node)
                                for i in range(0, 3):
                                    self.sensorProperties.position[i]= int(self.sensorProperties.position[i])*aux                        
                
                if element.nodeName.strip()=="Orientation":
                    for node in element.childNodes:
                        if node.nodeType==1:
                            if node.nodeName.strip()=="Value":
                                self.sensorProperties.orientation=self.read_node(node)
                            if node.nodeName.strip()=="Dimension":
                                aux = self.load_dimension(node)
                                for i in range(0, 3):
                                    self.sensorProperties.orientation[i]= int(self.sensorProperties.orientation[i])*aux
        self.load_measurement_format(baum)

class EventDataSheetParser(DataSheetParser, SensorDataSheetParser):

    def __init__(self, filename):
        self.channelProperties=ChannelProperties()
        self.sensorProperties=SensorProperties()
        self.channelProperties.channelDataSheet=filename
        
    def load_event_datasheet(self):
        baum = dom.parse(self.channelProperties.channelDataSheet.__str__())
        self.load_general(baum)
        self.load_event_format(baum)
        return self.channelProperties
 
    def load_general(self, baum):   
        aux = baum.getElementsByTagName('General')
        for element in aux[0].childNodes: 
            if element.nodeType==1:
                content = self.read_node(element)
                if element.nodeName.strip()=="Subject":
                    self.channelProperties.subject=content
                if element.nodeName.strip()=="Comment":
                    self.channelProperties.comment=content
                if element.nodeName.strip()=="Period":
                    for node in element.childNodes:
                        if node.nodeType==1:
                            if node.nodeName.strip()=="Value":
                                self.channelProperties.period=self.read_node(node)
                            if node.nodeName.strip()=="Dimension":
                                aux = self.load_dimension(node)
                                self.channelProperties.period=int(self.channelProperties.period)*aux
                            
    def load_event_format(self,baum):
        aux = baum.getElementsByTagName('EventFormat')
        for element in aux[0].childNodes:
            event_element={}
            if element.nodeType==1:
                event_element['Name']=element.nodeName.strip()
                for components in element.childNodes:
                    if components.nodeType==1:
                        if components.nodeName.strip()=="Dimension":
                            content = self.load_dimension(components)
                        else:
                            content = self.read_node(components)
                        event_element[components.nodeName.strip()]=content
                self.channelProperties.eventFormat.append(event_element)
    
